{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Perceptron"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Implementation of a Perceptron learning algorithm for classification."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> from mlxtend.classifier import Perceptron"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Overview"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The idea behind this \"thresholded\" perceptron was to mimic how a single neuron in the brain works: It either \"fires\" or not. \n",
    "A perceptron receives multiple input signals, and if the sum of the input signals exceed a certain threshold it either returns a signal or remains \"silent\" otherwise. What made this a \"machine learning\" algorithm was Frank Rosenblatt's idea of the perceptron learning rule: The perceptron algorithm is about learning the weights for the input signals in order to draw linear decision boundary that allows us to discriminate between the two linearly separable classes +1 and -1.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](./Perceptron_files/perceptron_schematic.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Basic Notation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Before we dive deeper into the algorithm(s) for learning the weights of the perceptron classifier, let us take a brief look at the basic notation. In the following sections, we will label the *positive* and *negative* class in our binary classification setting as \"1\" and \"-1\", respectively. Next, we define an activation function $g(\\mathbf{z})$ that takes a linear combination of the input values $\\mathbf{x}$ and weights $\\mathbf{w}$ as input ($\\mathbf{z} = w_1x_{1} + \\dots + w_mx_{m}$), and if $g(\\mathbf{z})$ is greater than a defined threshold $\\theta$ we predict 1 and -1 otherwise; in this case, this activation function $g$ is a simple \"unit step function,\" which is sometimes also called \"Heaviside step function.\" "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$$\n",
    " g(z) =\\begin{cases}\n",
    "    1 & \\text{if $z \\ge \\theta$}\\\\\n",
    "    -1 & \\text{otherwise}.\n",
    "  \\end{cases}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "where\n",
    "\n",
    "$$z =  w_1x_{1} + \\dots + w_mx_{m} = \\sum_{j=1}^{m} x_{j}w_{j} \\\\ = \\mathbf{w}^T\\mathbf{x}$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$\\mathbf{w}$ is the feature vector, and $\\mathbf{x}$ is an $m$-dimensional sample from the training dataset:\n",
    "\n",
    "$$ \n",
    "\\mathbf{w} = \\begin{bmatrix}\n",
    "    w_{1}  \\\\\n",
    "    \\vdots \\\\\n",
    "    w_{m}\n",
    "\\end{bmatrix}\n",
    "\\quad  \\mathbf{x} = \\begin{bmatrix}\n",
    "    x_{1}  \\\\\n",
    "    \\vdots \\\\\n",
    "    x_{m}\n",
    "\\end{bmatrix}$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In order to simplify the notation, we bring $\\theta$ to the left side of the equation and define $w_0 = -\\theta  \\text{ and } x_0=1$ \n",
    "\n",
    "so that \n",
    "\n",
    "$$\n",
    " g({z}) =\\begin{cases}\n",
    "    1 & \\text{if $z \\ge 0$}\\\\\n",
    "    -1 & \\text{otherwise}.\n",
    "  \\end{cases}\n",
    "$$\n",
    "\n",
    "and\n",
    "\n",
    "\n",
    "$$z = w_0x_{0} + w_1x_{1} + \\dots + w_mx_{m} = \\sum_{j=0}^{m} x_{j}w_{j} \\\\ = \\mathbf{w}^T\\mathbf{x}.$$\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Perceptron Rule"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Rosenblatt's initial perceptron rule is fairly simple and can be summarized by the following steps: \n",
    "\n",
    "1. Initialize the weights to 0 or small random numbers.\n",
    "2. For each training sample $\\mathbf{x^{(i)}}$:\n",
    "    2. Calculate the *output* value.\n",
    "    2. Update the weights."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The output value is the class label predicted by the unit step function that we defined earlier (output $=g(\\mathbf{z})$) and the weight update can be written more formally as  $w_j := w_j + \\Delta w_j$.\n",
    "\n",
    "The value for updating the weights at each increment is calculated by the learning rule\n",
    "\n",
    "$\\Delta w_j = \\eta \\; (\\text{target}^{(i)} - \\text{output}^{(i)})\\;x^{(i)}_{j}$\n",
    "\n",
    "where $\\eta$ is the learning rate (a constant between 0.0 and 1.0), \"target\" is the true class label, and the \"output\" is the predicted class label."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "aIt is important to note that all weights in the weight vector are being updated simultaneously. Concretely, for a 2-dimensional dataset, we would write the update as:\n",
    "\n",
    "$\\Delta w_0 = \\eta(\\text{target}^{(i)} - \\text{output}^{(i)})$  \n",
    "$\\Delta w_1 = \\eta(\\text{target}^{(i)} - \\text{output}^{(i)})\\;x^{(i)}_{1}$  \n",
    "$\\Delta w_2 = \\eta(\\text{target}^{(i)} - \\text{output}^{(i)})\\;x^{(i)}_{2}$  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Before we implement the perceptron rule in Python, let us make a simple thought experiment to illustrate how beautifully simple this learning rule really is. In the two scenarios where the perceptron predicts the class label correctly, the weights remain unchanged:\n",
    "\n",
    "- $\\Delta w_j = \\eta(-1^{(i)} - -1^{(i)})\\;x^{(i)}_{j} = 0$ \n",
    "- $\\Delta w_j = \\eta(1^{(i)} - 1^{(i)})\\;x^{(i)}_{j} = 0$ \n",
    "\n",
    "However, in case of a wrong prediction, the weights are being \"pushed\" towards the direction of the positive or negative target class, respectively:\n",
    "\n",
    "- $\\Delta w_j = \\eta(1^{(i)} - -1^{(i)})\\;x^{(i)}_{j} = \\eta(2)\\;x^{(i)}_{j}$ \n",
    "- $\\Delta w_j = \\eta(-1^{(i)} - 1^{(i)})\\;x^{(i)}_{j} = \\eta(-2)\\;x^{(i)}_{j}$ \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It is important to note that the convergence of the perceptron is only guaranteed if the two classes are linearly separable. If the two classes can't be separated by a linear decision boundary, we can set a maximum number of passes over the training dataset (\"epochs\") and/or a threshold for the number of tolerated misclassifications."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### References\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- F. Rosenblatt. The perceptron, a perceiving and recognizing automaton Project Para. Cornell Aeronautical Laboratory, 1957."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example 1 - Classification of Iris Flowers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Iteration: 5/5 | Elapsed: 00:00:00 | ETA: 00:00:00"
     ]
    },
    {
     "data": {
      "image/png": "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\nFAzMqOFsAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10ea71860>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Bias & Weights: [[-0.04500809]\n",
      " [ 0.11048855]]\n"
     ]
    },
    {
     "data": {
      "image/png": "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\nAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10eaf8eb8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from mlxtend.data import iris_data\n",
    "from mlxtend.plotting import plot_decision_regions\n",
    "from mlxtend.classifier import Perceptron\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# Loading Data\n",
    "\n",
    "X, y = iris_data()\n",
    "X = X[:, [0, 3]] # sepal length and petal width\n",
    "X = X[0:100] # class 0 and class 1\n",
    "y = y[0:100] # class 0 and class 1\n",
    "\n",
    "# standardize\n",
    "X[:,0] = (X[:,0] - X[:,0].mean()) / X[:,0].std()\n",
    "X[:,1] = (X[:,1] - X[:,1].mean()) / X[:,1].std()\n",
    "\n",
    "\n",
    "# Rosenblatt Perceptron\n",
    "\n",
    "ppn = Perceptron(epochs=5, \n",
    "                 eta=0.05, \n",
    "                 random_seed=0,\n",
    "                 print_progress=3)\n",
    "ppn.fit(X, y)\n",
    "\n",
    "plot_decision_regions(X, y, clf=ppn)\n",
    "plt.title('Perceptron - Rosenblatt Perceptron Rule')\n",
    "plt.show()\n",
    "\n",
    "print('Bias & Weights: %s' % ppn.w_)\n",
    "\n",
    "plt.plot(range(len(ppn.cost_)), ppn.cost_)\n",
    "plt.xlabel('Iterations')\n",
    "plt.ylabel('Missclassifications')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## API"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "## Perceptron\n",
      "\n",
      "*Perceptron(eta=0.1, epochs=50, random_seed=None, print_progress=0)*\n",
      "\n",
      "Perceptron classifier.\n",
      "\n",
      "Note that this implementation of the Perceptron expects binary class labels\n",
      "in {0, 1}.\n",
      "\n",
      "**Parameters**\n",
      "\n",
      "- `eta` : float (default: 0.1)\n",
      "\n",
      "    Learning rate (between 0.0 and 1.0)\n",
      "\n",
      "- `epochs` : int (default: 50)\n",
      "\n",
      "    Number of passes over the training dataset.\n",
      "    Prior to each epoch, the dataset is shuffled to prevent cycles.\n",
      "\n",
      "- `random_seed` : int\n",
      "\n",
      "    Random state for initializing random weights and shuffling.\n",
      "\n",
      "- `print_progress` : int (default: 0)\n",
      "\n",
      "    Prints progress in fitting to stderr.\n",
      "    0: No output\n",
      "    1: Epochs elapsed and cost\n",
      "    2: 1 plus time elapsed\n",
      "    3: 2 plus estimated time until completion\n",
      "\n",
      "**Attributes**\n",
      "\n",
      "- `w_` : 2d-array, shape={n_features, 1}\n",
      "\n",
      "    Model weights after fitting.\n",
      "\n",
      "- `b_` : 1d-array, shape={1,}\n",
      "\n",
      "    Bias unit after fitting.\n",
      "\n",
      "- `cost_` : list\n",
      "\n",
      "    Number of misclassifications in every epoch.\n",
      "\n",
      "**Examples**\n",
      "\n",
      "For usage examples, please see\n",
      "    [http://rasbt.github.io/mlxtend/user_guide/classifier/Perceptron/](http://rasbt.github.io/mlxtend/user_guide/classifier/Perceptron/)\n",
      "\n",
      "### Methods\n",
      "\n",
      "<hr>\n",
      "\n",
      "*fit(X, y, init_params=True)*\n",
      "\n",
      "Learn model from training data.\n",
      "\n",
      "**Parameters**\n",
      "\n",
      "- `X` : {array-like, sparse matrix}, shape = [n_samples, n_features]\n",
      "\n",
      "    Training vectors, where n_samples is the number of samples and\n",
      "    n_features is the number of features.\n",
      "\n",
      "- `y` : array-like, shape = [n_samples]\n",
      "\n",
      "    Target values.\n",
      "\n",
      "- `init_params` : bool (default: True)\n",
      "\n",
      "    Re-initializes model parameters prior to fitting.\n",
      "    Set False to continue training with weights from\n",
      "    a previous model fitting.\n",
      "\n",
      "**Returns**\n",
      "\n",
      "- `self` : object\n",
      "\n",
      "\n",
      "<hr>\n",
      "\n",
      "*predict(X)*\n",
      "\n",
      "Predict targets from X.\n",
      "\n",
      "**Parameters**\n",
      "\n",
      "- `X` : {array-like, sparse matrix}, shape = [n_samples, n_features]\n",
      "\n",
      "    Training vectors, where n_samples is the number of samples and\n",
      "    n_features is the number of features.\n",
      "\n",
      "**Returns**\n",
      "\n",
      "- `target_values` : array-like, shape = [n_samples]\n",
      "\n",
      "    Predicted target values.\n",
      "\n",
      "<hr>\n",
      "\n",
      "*score(X, y)*\n",
      "\n",
      "Compute the prediction accuracy\n",
      "\n",
      "**Parameters**\n",
      "\n",
      "- `X` : {array-like, sparse matrix}, shape = [n_samples, n_features]\n",
      "\n",
      "    Training vectors, where n_samples is the number of samples and\n",
      "    n_features is the number of features.\n",
      "\n",
      "- `y` : array-like, shape = [n_samples]\n",
      "\n",
      "    Target values (true class labels).\n",
      "\n",
      "**Returns**\n",
      "\n",
      "- `acc` : float\n",
      "\n",
      "    The prediction accuracy as a float\n",
      "    between 0.0 and 1.0 (perfect score).\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "with open('../../api_modules/mlxtend.classifier/Perceptron.md', 'r') as f:\n",
    "    print(f.read())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  },
  "toc": {
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
